#ifndef _WX_SCROLLINGDIALOG_H_
#define _WX_SCROLLINGDIALOG_H_

#include "wx/dialog.h"
#include "wx/propdlg.h"

class wxScrollingDialog;
class wxDialogHelper;
class wxBoxSizer;
class wxButton;
class wxScrolledWindow;

class wxDialogLayoutAdapter: public wxObject {
    DECLARE_CLASS( wxDialogLayoutAdapter )
  public:
    wxDialogLayoutAdapter() {}
    virtual bool CanDoLayoutAdaptation( wxDialogHelper* dialog ) = 0;
    virtual bool DoLayoutAdaptation( wxDialogHelper* dialog ) = 0;
};

class wxStandardDialogLayoutAdapter: public wxDialogLayoutAdapter {
    DECLARE_CLASS( wxStandardDialogLayoutAdapter )
  public:
    wxStandardDialogLayoutAdapter() {}
    virtual bool CanDoLayoutAdaptation( wxDialogHelper* dialog );
    virtual bool DoLayoutAdaptation( wxDialogHelper* dialog );
    virtual wxSizer* FindButtonSizer( bool stdButtonSizer, wxDialogHelper* dialog, wxSizer* sizer, int& retBorder, int accumlatedBorder = 0 );
    virtual bool IsOrdinaryButtonSizer( wxDialogHelper* dialog, wxBoxSizer* sizer );
    virtual bool IsStandardButton( wxDialogHelper* dialog, wxButton* button );
    virtual bool FindLooseButtons( wxDialogHelper* dialog, wxStdDialogButtonSizer* buttonSizer, wxSizer* sizer, int& count );
    virtual void ReparentControls( wxWindow* parent, wxWindow* reparentTo, wxSizer* buttonSizer = NULL );
    virtual bool FitWithScrolling( wxDialog* dialog, wxScrolledWindow* scrolledWindow );
    virtual bool FitWithScrolling( wxDialog* dialog, wxWindowList& windows );
    virtual int MustScroll( wxDialog* dialog, wxSize& windowSize, wxSize& displaySize );
};

class wxDialogHelper {
  public:
    wxDialogHelper( wxDialog* dialog = NULL ) { Init(); m_dialog = dialog; }
    virtual ~wxDialogHelper() {}
    void Init();
    void SetDialog( wxDialog* dialog ) { m_dialog = dialog; }
    wxDialog* GetDialog() const { return m_dialog; }
    virtual bool DoLayoutAdaptation();
    virtual bool CanDoLayoutAdaptation();
    virtual wxWindow* GetContentWindow() const { return NULL; }
    void AddButtonId( wxWindowID id ) { m_buttonIds.Add( ( int ) id ); }
    wxArrayInt& GetButtonIds() { return m_buttonIds; }
    bool IsUserButtonId( wxWindowID id ) { return ( m_buttonIds.Index( ( int ) id ) != wxNOT_FOUND ); }
    void SetLayoutAdaptationLevel( int level ) { m_layoutAdaptationLevel = level; }
    int GetLayoutAdaptationLevel() const { return m_layoutAdaptationLevel; }
    void SetLayoutAdaptationDone( bool adaptationDone ) { m_layoutLayoutAdaptationDone = adaptationDone; }
    bool GetLayoutAdaptationDone() const { return m_layoutLayoutAdaptationDone; }
    static wxDialogLayoutAdapter* SetLayoutAdapter( wxDialogLayoutAdapter* adapter );
    static wxDialogLayoutAdapter* GetLayoutAdapter() { return sm_layoutAdapter; }
    static bool GetLayoutAdaptation() { return sm_layoutAdaptation; }
    static void SetLayoutAdaptation( bool enable ) { sm_layoutAdaptation = enable; }
  protected:
    wxDialog* m_dialog;
    bool m_layoutLayoutAdaptationDone;
    wxArrayInt m_buttonIds;
    int m_layoutAdaptationLevel;
    static wxDialogLayoutAdapter* sm_layoutAdapter;
    static bool sm_layoutAdaptation;
};

class wxScrollingDialog: public wxDialog
  , public wxDialogHelper {
    DECLARE_CLASS( wxScrollingDialog )
  public:
    wxScrollingDialog() {
      Init();
    }
    wxScrollingDialog( wxWindow *parent,
                       int id = wxID_ANY,
                       const wxString& title = wxEmptyString,
                       const wxPoint& pos = wxDefaultPosition,
                       const wxSize& size = wxDefaultSize,
                       long style = wxDEFAULT_DIALOG_STYLE,
                       const wxString& name = _T( "dialogBox" ) ) {
      Init();
      Create( parent, id, title, pos, size, style, name );
    }
    bool Create( wxWindow *parent,
                 int id = wxID_ANY,
                 const wxString& title = wxEmptyString,
                 const wxPoint& pos = wxDefaultPosition,
                 const wxSize& size = wxDefaultSize,
                 long style = wxDEFAULT_DIALOG_STYLE,
                 const wxString& name = _T( "dialogBox" ) );

    void Init();
    virtual bool Show( bool show = true );
    virtual int ShowModal();
};

class wxScrollingPropertySheetDialog : public wxPropertySheetDialog, public wxDialogHelper {
  public:
    wxScrollingPropertySheetDialog() : wxPropertySheetDialog() {
      Init();
    }
    wxScrollingPropertySheetDialog( wxWindow* parent, wxWindowID id,
                                    const wxString& title,
                                    const wxPoint& pos = wxDefaultPosition,
                                    const wxSize& sz = wxDefaultSize,
                                    long style = wxDEFAULT_DIALOG_STYLE,
                                    const wxString& name = wxDialogNameStr ) {
      Init();
      Create( parent, id, title, pos, sz, style, name );
    }

    virtual wxWindow* GetContentWindow() const;
    virtual bool Show( bool show = true );
    virtual int ShowModal();
  private:
    void Init();
  protected:
    DECLARE_DYNAMIC_CLASS( wxScrollingPropertySheetDialog )
};

#endif
